#ifndef TB_HASH_SHA_H
#define TB_HASH_SHA_H

#include "prefix.h"

__tb_extern_c_enter__

typedef struct __tb_sha_t {
    tb_uint8_t digest_len;
    tb_hize_t count;
    tb_uint8_t buffer[64];
    tb_uint32_t state[8];
    tb_void_t (*transform)(tb_uint32_t *state, tb_uint8_t const buffer[64]);
} tb_sha_t;

typedef enum __tb_sha_mode_t {
    TB_SHA_MODE_SHA1_160 = 160,
    TB_SHA_MODE_SHA2_224 = 224,
    TB_SHA_MODE_SHA2_256 = 256
} tb_sha_mode_t;

/*! init sha
 *
 * @param sha           the sha
 * @param mode          the mode
 */
tb_void_t               tb_sha_init(tb_sha_t* sha, tb_size_t mode);

/*! exit sha
 *
 * @param sha           the sha
 * @param data          the data
 * @param size          the size
 */
tb_void_t               tb_sha_exit(tb_sha_t* sha, tb_byte_t* data, tb_size_t size);

/*! spak sha
 *
 * @param sha           the sha
 * @param data          the data
 * @param size          the size
 */
tb_void_t               tb_sha_spak(tb_sha_t* sha, tb_byte_t const* data, tb_size_t size);

/*! make sha
 *
 * @param mode          the mode
 * @param ib            the input data
 * @param ip            the input size
 * @param ob            the output data
 * @param on            the output size
 *
 * @return              the real size
 */
tb_size_t               tb_sha_make(tb_size_t mode, tb_byte_t const* ib, tb_size_t ip, tb_byte_t* ob, tb_size_t on);

__tb_extern_c_leave__

#endif // !TB_HASH_SHA_H
